package com.vegetable.modules.service.baseData.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vegetable.common.utils.BankCardRedisService;
import com.vegetable.common.utils.BankNoRedisService;
import com.vegetable.common.utils.PageUtils;
import com.vegetable.common.utils.Query;
import com.vegetable.modules.entity.baseData.AddressBook;
import com.vegetable.modules.entity.baseData.po.AddressBookQueryDTO;
import com.vegetable.modules.mapper.baseData.AddressBookMapper;
import com.vegetable.modules.service.baseData.IAddressBookService;
import com.vegetable.modules.entity.sys.SysUserEntity;
import com.vegetable.modules.mapper.sys.SysUserDao;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 通讯录（农户,客商,代办,班组） 服务实现类
 * </p>
 *
 * @author wangruijie
 * @since 2024-03-07
 */
@Slf4j
@Service
@AllArgsConstructor
public class AddressBookServiceImpl extends ServiceImpl<AddressBookMapper, AddressBook> implements IAddressBookService {

    @Autowired
    private BankNoRedisService bankNoRedisService;
    
    @Autowired
    private BankCardRedisService bankCardRedisService;
    
    private final AddressBookMapper addressBookMapper;
    
    private final SysUserDao sysUserDao;

    /**
     * 通讯录
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        // 通讯录类型
        String staffType = (String)params.get("staffType");
        String salesman = (String)params.get("salesman");
        String salesmanId = (String)params.get("salesmanId");
        String noteName = (String)params.get("noteName");
        Integer staffType_int = null;
        if (StringUtils.isNotBlank(staffType)){
            staffType_int = Integer.valueOf(staffType);
        }
        String isDel = (String)params.get("isDel");
        Integer isDel_int = 0;
        if (StringUtils.isNotBlank(isDel)){
            isDel_int = Integer.valueOf(isDel);
        }
        QueryWrapper<AddressBook> queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isNotNull(staffType_int)){
            // TODO 特殊处理
            if(staffType_int == 4){
                queryWrapper.in("staff_type", Arrays.asList(0, 2));
            }else if(staffType_int == 5){
                queryWrapper.in("staff_type", Arrays.asList(2, 3));
            }else if(staffType_int == 6) {
                queryWrapper.in("staff_type", Arrays.asList(0, 1, 2, 3));
            }else{
                queryWrapper.eq("staff_type", staffType_int);
            }
        }
        queryWrapper.eq(ObjectUtils.isNotEmpty(isDel_int),"is_del", isDel_int);
        queryWrapper.like(StringUtils.isNotBlank(noteName),"note_name", noteName);
        
        // 支持通过业务员姓名或业务员ID查询
        if(StringUtils.isNotBlank(salesman)){
            queryWrapper.like("salesman", salesman);
        }
        if(StringUtils.isNotBlank(salesmanId)){
            queryWrapper.eq("salesman_id", Long.valueOf(salesmanId));
        }
        
        queryWrapper.last("order by CONVERT(note_name using gbk)");
        IPage<AddressBook> page = this.page(new Query<AddressBook>().getPage(params), queryWrapper);

        return new PageUtils(page);
    }

    /**
     * 通讯录分页查询（使用DTO参数）
     * @param queryDTO 查询参数DTO
     * @return 分页结果
     */
    @Override
    public PageUtils queryPage(AddressBookQueryDTO queryDTO) {
        // 处理特殊查询条件
        if (ObjectUtil.isNotNull(queryDTO.getStaffType())) {
            Integer staffType = queryDTO.getStaffType();
            // 特殊处理类型4、5、6
            if (staffType == 4 || staffType == 5 || staffType == 6) {
                // 对于这些特殊类型，使用原来的查询逻辑
                return queryPageWithSpecialType(queryDTO);
            }
        }
        
        // 使用联合查询直接获取业务员姓名
        IPage<AddressBook> page = new Page<>(queryDTO.getPage(), queryDTO.getLimit());
        IPage<AddressBook> resultPage = addressBookMapper.selectAddressBookPageWithSalesman(page, queryDTO);
        
        // 对结果进行排序
        if (resultPage.getRecords() != null && !resultPage.getRecords().isEmpty()) {
            // 按照客户名称排序
            resultPage.getRecords().sort((a, b) -> {
                if (a.getNoteName() == null) return -1;
                if (b.getNoteName() == null) return 1;
                return a.getNoteName().compareTo(b.getNoteName());
            });
        }
        
        return new PageUtils(resultPage);
    }
    
    /**
     * 处理特殊类型的查询
     * @param queryDTO 查询参数
     * @return 分页结果
     */
    private PageUtils queryPageWithSpecialType(AddressBookQueryDTO queryDTO) {
        // 构建查询条件
        QueryWrapper<AddressBook> queryWrapper = new QueryWrapper<>();
        
        // 人员类型查询
        if(ObjectUtil.isNotNull(queryDTO.getStaffType())){
            Integer staffType = queryDTO.getStaffType();
            // 特殊处理
            if(staffType == 4){
                queryWrapper.in("staff_type", Arrays.asList(0, 2));
            }else if(staffType == 5){
                queryWrapper.in("staff_type", Arrays.asList(2, 3));
            }else if(staffType == 6) {
                queryWrapper.in("staff_type", Arrays.asList(0, 1, 2, 3));
            }else{
                queryWrapper.eq("staff_type", staffType);
            }
        }
        
        // 删除标识查询
        if(ObjectUtil.isNotNull(queryDTO.getIsDel())){
            queryWrapper.eq("is_del", queryDTO.getIsDel());
        } else {
            queryWrapper.eq("is_del", 0);
        }
        
        // 客户名称模糊查询
        if(StringUtils.isNotBlank(queryDTO.getNoteName())){
            queryWrapper.like("note_name", queryDTO.getNoteName());
        }
        
        // 业务员姓名查询
        if(StringUtils.isNotBlank(queryDTO.getSalesman())){
            queryWrapper.like("salesman", queryDTO.getSalesman());
        }
        
        // 业务员ID查询
        if(ObjectUtil.isNotNull(queryDTO.getSalesmanId())){
            queryWrapper.eq("salesman_id", queryDTO.getSalesmanId());
        }
        
        queryWrapper.last("order by CONVERT(note_name using gbk)");
        
        // 执行分页查询
        IPage<AddressBook> page = this.page(
            new Query<AddressBook>().getPage(
                new HashMap<String, Object>() {{
                    put("page", queryDTO.getPage() + "");
                    put("limit", queryDTO.getLimit() + "");
                }}
            ), 
            queryWrapper
        );
        
        // 如果有业务员ID，需要联合sys_user表获取真实的业务员姓名
        if (page.getRecords() != null && !page.getRecords().isEmpty()) {
            // 收集所有业务员ID
            Set<Long> salesmanIds = page.getRecords().stream()
                .map(AddressBook::getSalesmanId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
            
            if (!salesmanIds.isEmpty()) {
                // 查询sys_user表获取业务员真实姓名
                QueryWrapper<SysUserEntity> userQueryWrapper = new QueryWrapper<>();
                userQueryWrapper.in("user_id", salesmanIds);
                List<SysUserEntity> userList = sysUserDao.selectList(userQueryWrapper);
                
                // 构建业务员ID到真实姓名的映射
                Map<Long, String> salesmanMap = userList.stream()
                    .collect(Collectors.toMap(SysUserEntity::getUserId, SysUserEntity::getRealName));
                
                // 更新通讯录记录中的业务员姓名
                page.getRecords().forEach(addressBook -> {
                    Long salesmanId = addressBook.getSalesmanId();
                    if (salesmanId != null && salesmanMap.containsKey(salesmanId)) {
                        addressBook.setSalesman(salesmanMap.get(salesmanId));
                    }
                });
            }
        }

        return new PageUtils(page);
    }

    @Override
    public AddressBook queryByName(String name , Integer staffType) {
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.eq("note_name", name);
        wrapper.eq("staff_type", staffType);
        wrapper.eq("is_del", 0);
       return this.getOne(wrapper);
    }

    @Override
    public AddressBook queryByAliseName(String aliasName, Integer staffType) {
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.eq("alias", aliasName);
        wrapper.eq("staff_type", staffType);
        wrapper.eq("is_del", 0);
        return this.getOne(wrapper);
    }

    @Override
    public List<AddressBook> queryByNameList(List<String> customerNames, Integer staffType) {
        QueryWrapper queryWrapper = new QueryWrapper<AddressBook>();
        queryWrapper.in("note_name", customerNames);
        queryWrapper.eq("staff_type", staffType);
        return this.list(queryWrapper);
    }

    @Override
    public AddressBook queryById(Long addressId) {
        return this.getById(addressId);
    }

    @Override
    public void updateBandNo(Long abId, String oldBankNos, String newBankNo) {
        log.info("abId:{}, 旧的银行卡号:{}, 新的银行卡号:{}", abId, oldBankNos, newBankNo);
        // 此方法已废弃，银行卡号现在通过BankCard实体管理
        log.warn("updateBandNo方法已废弃，请使用BankCard相关接口");
    }

    @Override
    public AddressBook selectByBankNo(String bankNo) {
        // 此方法已废弃，银行卡号现在通过BankCard实体管理
        return null;
    }

    @Override
    public AddressBook selectByMobile(String mobile) {
        QueryWrapper<AddressBook> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", mobile);
        queryWrapper.eq("is_del", 0);
        return this.getOne(queryWrapper);
    }

    @Override
    public boolean removeById(Long id) {
        AddressBook updater = new AddressBook();
        updater.setId(id);
        updater.setIsDel(1);
        return this.updateById(updater);
    }
}